home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-07
/
book.exe
/
LAN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-22
|
19KB
|
711 lines
/*
// LAN.C LAN information utility
//
// (c) Copyright 1990, 1991 Adrian King.
//
//
// This code was developed for inclusion in the book
// "Running LANtastic", by Adrian King, published by
// Bantam Books, October 1991.
//
// This product uses the TesSeRact(tm) Ram-Resident Library and
// supports the TesSeRact Standard for Ram-Resident Program Comm-
// unication. For information about TesSeRact, contact the TesSeRact
// Development Team at:
//
// TesSeRact Development Team
// 1657 The Fairways
// Suite 101
// Jenkintown PA 19046
// 1-215-884-3373
//
// Compuserve: 70731,20
// MCIMAIL: 315-5415
//
// This is the main module for the foreground program. It analyzes
// the command and parameters, and generates any necessary network
// messages and display output.
//
// LANRES must be loaded before some functions will work.
//
// Make sure to compile this program with a -DFOREGROUND switch.
//
// $Header: C:/USR/LANBOOK/SRC2/LAN/VCS/LAN.C_V 1.3 22 Sep 1991 9:15:54 $
//
// $Log: C:/USR/LANBOOK/SRC2/LAN/VCS/LAN.C_V $
*
* Rev 1.3 22 Sep 1991 9:15:54
* Added correct TesSeRact copyright notice.
*
* Rev 1.2 22 Sep 1991 9:00:42
* Added the ability to terminate LAN SYNC by pressing a key.
//
// Rev 1.1 29 Aug 1991 12:42:36
// Modification to screen layout of LAN STATUS
//
// Rev 1.0 13 Jul 1991 11:12:58
// Initial revision.
//
*/
// Standard DOS includes
#include "stdio.h"
#include "conio.h"
#include "process.h"
#include "dos.h"
#include "string.h"
#include "ctype.h"
// NOS specific includes
#include "nos.h"
#include "noslib.h"
#include "lan.h"
// Includes for TesSeRact interface
#include "tess.h"
// Forward declarations
extern void far lansync(); // Command processing routines
extern void far lanboot();
extern void far lanstatus();
extern void far lansend();
extern void far lanhelp();
extern struct lancmd *parsecmd(); // Parse command line
extern int argival(); // Get integer value of argument
extern char *argsval(); // Get string value of argument
extern void far reboot(); // Reboot the machine
extern void getnodetable(); // Get node table from LANRES
// Local defines
#define ARGVALERR -32767
// Global data
char cpMyname[] = "FIFTEENCHRACTRS"; // Set to this machine's name
//
// Command table. Switch through this to carry out a specific
// LAN program function.
//
struct lancmd {
char *cpCmd; // Pointer to LAN function name
BOOL bNeedLib; // TRUE if LANLIB must be loaded
// for this function, FALSE if not
FARPROC fpFunc; // Pointer to routine that executes
// this function
};
struct lancmd lancmd [] = { // Table of recognised commands
"SYNC", FALSE, lansync, // Synchronize the LAN
"BOOT", FALSE, lanboot, // Reboot the LAN
"STATUS", TRUE, lanstatus, // Get status of LAN
"SEND", FALSE, lansend, // Broadcast a message to the LAN
"HELP", FALSE, lanhelp, // Print some help
"?", FALSE, lanhelp,
"/?", FALSE, lanhelp,
(char *)0, FALSE, (FARPROC)0 // Null entry to terminate table
};
//
// MAIN
//
void main(argc, argv, envp)
int argc;
char *argv[];
char *envp[];
{
char *cp;
BOOL bName;
int m, n;
struct lancmd *lc;
printf("LAN version 1.0 - (C) Copyright 1991 Adrian King\n");
if (argc == 1) // No arguments?
lanhelp((char *)0); // Print help and quit.
lc = parsecmd(argv[1]); // Find out which command
if (lc->cpCmd == (char *)0) // Print help if unrecognizable
lanhelp((char *)0);
n = NOSPresence(); // Check LANBIOS and REDIR present
if ((n == -1)||((n & D_redir) == 0))
FATAL(E_NOLAN);
if (NOSGetMachineName(cpMyname, &m, &bName) == -1)
FATAL(E_GETNAME);
if (!bName) // Name must be set
FATAL(E_NONAME);
initnodetable(); // Clear network node table
cp = strchr(cpMyname, ' ');
if (cp != NULL)
*cp = '\0'; // Null terminate the name
addname(cpMyname, n); // Add name to local table
// (Must always be entry 0.)
// Call command processor.
// Do not pass LAN FUNC arguments
(lc->fpFunc)(lc, argc-2,&argv[2], envp);
exit(0); // Normal exit
}
//
// PRINTHELP
//
// Print help text
//
void printhelp(cp)
char *cp;
{
// Print command specific help if called with an argument
if (cp != (char *)0){
printf("LAN: Help for %s not yet available\n", cp);
exit(0);
}
// Otherwise print general help
printf("\n\
Available commands for LAN are:\n\n\
LAN HELP or LAN /? Display this help message\n\
LAN SEND Message Broadcast a message\n\
LAN SYNC [/HOST=name] Synchronize hosts\n\
LAN BOOT [/BOOT=[warm|cold]] [/HOST=name] Reboot the network\n\
LAN STATUS Show network status\n\
");
}
//
// LANHELP
//
// Command processor for LAN HELP, LAN HELP Command, LAN ? and LAN /?
//
// Arguments are passed but never used
//
void far lanhelp()
{
printhelp((char *)0); // Call general help and quit
exit(0);
}
//
// LANSYNC
//
// Command processor for LAN SYNC [/TIMEOUT=timeout] host [host...]
//
void far lansync(lcp, argc, argv)
struct lancmd *lcp;
int argc;
char *argv[];
{
int timeout; // Timeout while trying to sync
int nHosts; // Number of hosts to sync with
int i, j;
int nAdapter;
char cpNode[D_NAMESZ];
BOOL bSynced;
struct message_buffer m;
if (lcp->bNeedLib) // Check resident library is there if we need it
lanlibcheck();
timeout = argival("/TIMEOUT", argc, argv); // Look for timeout value
if (timeout != ARGVALERR){ // Found?
if (argc == 1) // Yes.
FATAL(E_NOHOST); // But no host specified.
else
nHosts = argc - 1; // Set # of hosts
} else {
// Couldn't find the /TIMEOUT argument so set it to default
timeout = D_TIMEOUT;
nHosts = argc; // Set # of hosts
}
// Collect node names
// for syncing
while ((timeout > 0) && (nHosts > 0)){
bSynced = FALSE;
// Scan through all command arguments each time
for (i = 0; i < argc; i++){
// Ignore /TIMEOUT argument and any host
// names that were already found
if ((argv[i][0] != '/') && (argv[i][0] != '\0')){
printf("Trying to sync with host %s inside %d seconds, press any key to abort...\n",
argv[i], timeout);
// Check if its a self sync...
if (nodenamecmp(lannode[0].cpName, argv[i]) == 0){
printf("Found host %s\n", argv[i]);
// Null it so we don't look at it again
argv[i][0] = '\0';
nHosts--;
continue;
}
j = 0; // First check all the current logins
while (NOSGetLogin(&j, cpNode, &nAdapter) != -1){
if (nodenamecmp(cpNode, argv[i]) == 0){
printf("Found host %s\n", argv[i]);
// Null it so we don't look at it again
argv[i][0] = '\0';
nHosts--;
bSynced = TRUE;
break;
}
j++;
};
// Move on if we're already synced
if (bSynced)
continue;
// Check other available servers
j = 0;
while (NOSGetServer(&j, cpNode, &nAdapter) != -1){
if (nodenamecmp(cpNode, argv[i]) == 0){
printf("Found host %s\n", argv[i]);
// Null it so we don't look at it again
argv[i][0] = '\0';
nHosts--;
bSynced = TRUE;
break;
}
j++;
};
// Move on if we're synced
if (bSynced)
continue;
// Machine doesn't appear to be available
// as a server. We could send a message and
// see if it responds. However, if it's a
// server just booting up we'll cause popups
// every second - bad idea.
}
if (kbhit()){ // Don't look at this server again if a key
// has been pressed
(void)getch();
argv[i][0] = '\0';
nHosts--;
}
}
delay(1000); // Wait for 1 second before trying again
timeout--;
}
exit(nHosts); // Exit code is zero if all synced,
// non-zero otherwise
}
//
// LANSEND
//
// Command processor for LAN SEND Message
//
void far lansend(lcp, argc, argv)
struct lancmd *lcp;
int argc;
char *argv[];
{
int i;
struct message_buffer M;
if (lcp->bNeedLib) // Check resident library is there if we need it
lanlibcheck();
if (argc == 0){
printhelp("SEND"); // No parameters, assume it's an error
exit(1);
}
//
// NOTES:
//
// Should add multiple adapter support
//
// Could add a parameter that says broadcast only to logged
// in users rather than the entire network.
//
// Send the message with a null machine name.
// Everyone will get it.
if (sendmessage(&M, "", MBT_LANtext, argv[0], strlen(argv[0])) == -1)
NOSperror("LAN - error sending LAN message");
}
//
// LANBOOT
//
// Command processor for LAN BOOT [/BOOT=warmboot|coldboot] [host]
//
// host parameter is of the form /HOST=MACHINE to boot just MACHINE
// or NAME1 NAME2 NAME3... in order to boot a list of hosts.
//
// No parameter means boot this machine. When we boot ourselves we
// send ourselves a message so that if remote booting has been
// disabled we take account of that.
//
// The special name NETWORK means reboot the whole network
//
void far lanboot(lcp, argc, argv)
struct lancmd *lcp;
int argc;
char *argv[];
{
char *cpHost; // Name of host to boot
char *cpBoot; // Warm or cold boot
int nHosts; // # of hosts to go boot
int i;
int nBoot; // Type of boot
struct message_buffer M;// Message buffer to use
if (lcp->bNeedLib) // Check resident library is there if we need it
lanlibcheck();
// Check for warm or cold boot. Default is warm.
cpBoot = argsval("/BOOT", argc, argv);
// Reduce arg count if we found the string
if (cpBoot != NULL)
argc--;
if (stricmp(cpBoot, "COLD") == 0){
nBoot = MBT_LANcoldboot;
cpBoot = "COLD Reboot requested";
} else {
nBoot = MBT_LANwarmboot;
cpBoot = "WARM Reboot requested";
}
// Get the name of the host to go boot
cpHost = argsval("/HOST", argc, argv);
if (cpHost != NULL){ // Found a /HOST specification?
// Yes, do we mean the whole network?
if (stricmp(cpHost, "NETWORK") == 0)
nHosts = -1; // Yes
else {
nHosts = 1; // One host only
}
} else {
if (argc == 0){ // No /HOST switch. If there are no
nHosts = 1; // parameters we boot just ourselves
cpHost = lannode[0].cpName;
} else {
nHosts = argc; // Assume all parameters are host names
cpHost = argv[0]; // Set up first host name.
}
}
switch (nHosts){
case 1: // Boot one named host
if (sendmessage(&M, cpHost, nBoot, cpBoot, strlen(cpBoot)) == -1)
FATAL(E_MSGERR);
break;
case -1: // Boot the network
if (sendmessage(&M, "", nBoot, cpBoot, strlen(cpBoot)) == -1)
FATAL(E_MSGERR);
break;
default:
for (i = 0; i < nHosts; i ++)
if (argv[i][0] != '/'){
if (sendmessage(&M, argv[i], nBoot, cpBoot,
strlen(cpBoot)) == -1)
FATAL(E_MSGERR);
} else
i--; // Horrible hack to allow /TIMEOUT
// argument to be anywhere on the
// command line.
}
}
//
// LANSTATUS
//
// Command processor for LAN STATUS, a more comprehensive
// form of LANSHOW or NET SHOW.
//
void far lanstatus(lcp)
struct lancmd *lcp;
{
int i, j;
char cpServer[D_NAMESZ+2], cpUsername[D_NAMESZ];
struct logical_stream s;
struct PS ps;
char *printers[5] = { "LPT1", "LPT2", "LPT3", "COM1", "COM2" };
BOOL b = FALSE;
if (lcp->bNeedLib) // Check resident library is there
lanlibcheck();
//
// This causes a broadcast asking for all the network nodes
// to respond. The responses will be collected in the
// background by LANRES. By the time we get to the end of
// this routine we should have all the responses. This is,
// of course, unreliable and running LAN STATUS twice in
// succession may give you different results.
//
refreshnames();
j = NOSGetVersion(); // Get and report NOS version number
// and machine name
printf("\nLANtastic version %d.%02d running on \\\\%s\n\n",
j>>8, j&0xFF, lannode[0].cpName);
// Report our own status
// LANBIOS must be there if anything is
printf("LANBIOS........installed\n");
if (lannode[0].wFlags & D_redir)
printf("Redirector.....installed\n");
else
printf("Redirector.not.installed\n");
if (lannode[0].wFlags & D_server)
printf("Server.........installed\n");
else
printf("Server.....not.installed\n");
if (lannode[0].wFlags & D_lanpup)
printf("LANPUP.........installed\n");
else
printf("LANPUP.....not.installed\n");
// Report disposition of message service
NOSGetMsgFlag(&i);
if (i == -1)
FATAL(E_GETMSGFLAG); // Unexpected error
printf("Messages.will.%s\n",
(i & MPB_beep)?"......BEEP":".not.BEEP");
printf("Messages.will.%s\n",
(i & MPB_auto_pop_up)?".....POP UP":".not.POP UP");
//
// Now report on the network servers. Sometimes this can be
// misleading, since a server can go down and LANtastic won't
// figure that out for a little while.
//
// Report what we are logged into
printf("\nActive servers you are logged into:\n");
i = 0;
while (NOSGetLogin(&i, &cpServer[2], &j) != -1){
if (NOSGetUserName(&i, cpUsername, &j) != -1)
printf("\n\t%.16s as %s on adapter #%d\n",
&cpServer[2], cpUsername, j);
// Prefix server name with \\
cpServer[0] = cpServer[1] = '\\';
// Report status of physical printers
printf("\t\tPrinter ports:\n");
while (NOSGetStatus(&j, &ps, cpServer) != -1){
// Only list enabled ports
if (ps.PS_state.PS_state_value != 0)
printf("\t\t\t%-12s\t%s\n", printers[j-1], "ENABLED");
}
// Report status of printer streams
j = 0;
printf("\t\tPrinter streams:\n");
while (NOSGetStreamInfo(&j, &s, cpServer) != -1){
if (s.LS_template[0] != '@')
continue; // Stream is not in use
// Print stream info
printf("\t\t\t%.12s\t%s\n", s.LS_template,
(s.LS_queue == 0)? "DISABLED" : "ENABLED");
}
i++; // Increment index for next loop
b = TRUE; // Show we found at least one
};
if (!b)
printf("\n\tNone\n"); // Not logged into any servers
// Report other available servers
printf("\nOther active servers available for login:\n\n");
b = FALSE;
i = 0;
while (NOSGetServer(&i, cpServer, &j) != -1){
b = TRUE; // Show we found one
printf("\t%.16son adapter #%d\n", cpServer, j);
i++; // Increment index
};
if (!b)
printf("\tNone\n"); // No available servers
// Report other workstations
printf("\nOther active workstations:\n\n");
delay(5000); // Delay 5 seconds for all replies.
getnodetable(); // Update our node table.
b = FALSE;
for (i = 1; i < D_NODES; i++){ // Don't list ourselves, and ignore
// empty entries and servers. They
// were already reported.
if((lannode[i].cpName[0] != '\0') && !(lannode[i].wFlags & D_server)){
printf("\t%.16s\n", lannode[i].cpName);
b = TRUE;
}
}
if (!b)
printf("\tNone\n"); // No other workstations found
}
//
// GETNODETABLE
//
// Copies the current network node table from the background copy
// maintained by LANRES.
//
void getnodetable()
{
void far *fp = (void far *)&lannode[1];
//
// Call LANRES via the TesSeRact library.
// Pass in the pointer to the network node table.
//
(void)TsCallUserProc(TSRid, fp);
}
//
// PARSECMD
//
// Parse the LAN command line, return a pointer to the lancmd
// table entry.
//
struct lancmd *parsecmd(cmd)
char *cmd;
{
struct lancmd *lc = &lancmd[0];
int i;
// Try to find this command in the table
while (lc->cpCmd != (char *)0)
if (stricmp(cmd, lc->cpCmd) == 0)
return(lc);
else
lc++;
return(lc);
}
//
// ARGIVAL
//
// Find value of argument identified by argstr. For example,
// if you want to extract the value 19 from the command switch
// argument "/HOSTS=19", then call this function with argstr
// set to "/HOSTS" and it will return the value 19 if any of the
// the other string parameters (the argv parameter) match either
// "/HOSTS" or "/hosts" or "/HoSts" or "/HOSts" or...
//
// The check for the "=" character is done within this routine.
// The number of char *'s held in argv is specified by the value
// of argc.
//
// This function returns ARGVALERR if it cannot match argstr with
// the leading characters of the other arguments. This means that
// you cannot obtain a paramter value of ARGVALERR from this routine.
//
// The other parameters to this function are usually argc,
// argv and envp as inherited by the program. If others are
// used, then they must be of the same format.
//
int argival(argstr, argc, argv)
char *argstr;
int argc;
char *argv[];
{
int i, len;
if (argc < 1)
return (ARGVALERR); // Nothing to search through
len = strlen(argstr); // Length of string to match
for (i = 0; i < argc; i++){
if ((strnicmp(argstr, argv[i], len) == 0)
&& (argv[i][len] == '='))
// Found a match
return(atoi(&argv[i][len+1]));
}
return(ARGVALERR); // No match
}
//
// ARGSVAL
//
// Find string value of argument identified by argstr. For example,
// if you want to extract the string ERIC from the command switch
// argument "/HOST=ERIC", then call this function with argstr
// set to "/HOSTS" and it will return the string ERIC if any of the
// the other string parameters (the argv parameter) match either
// "/HOST" or "/host" or "/HoSt" or "/HOSt" or...
//
// The check for the "=" character is done within this routine.
// The number of char *'s held in argv is specified by the value
// of argc.
//
// This function returns NULL if it cannot match argstr with
// the leading characters of the other arguments.
//
// The other parameters to this function are usually argc,
// argv and envp as inherited by the program. If others are
// used, then they must be of the same format.
//
char *argsval(argstr, argc, argv)
char *argstr;
int argc;
char *argv[];
{
int i, len;
if (argc < 1)
return (NULL); // Nothing to search through
len = strlen(argstr); // Length of string to match
for (i = 0; i < argc; i++){
if ((strnicmp(argstr, argv[i], len) == 0)
&& (argv[i][len] == '='))
// Found a match
return(&argv[i][len+1]);
}
return(NULL); // No match
}